package cn.heyige.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.heyige.backend.dto.DivinationFeedbackDTO;
import cn.heyige.backend.entity.DivinationFeedbackDO;
import cn.heyige.backend.mapper.FeedbackMapper;
import cn.heyige.backend.service.FeedbackService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 占卜反馈服务实现类 - 精简版
 *
 * 专注于核心反馈管理功能，提高系统性能和可维护性
 * 增强数据验证和错误处理
 *
 * @author CodeBuddy
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FeedbackServiceImpl implements FeedbackService {
    
    private final FeedbackMapper feedbackMapper;
    
    private static final int DEFAULT_PAGE_SIZE = 20;
    private static final int MAX_PAGE_SIZE = 100;
    
    @Override
    public DivinationFeedbackDO saveFeedback(DivinationFeedbackDO feedback) {
        // 参数校验
        if (feedback == null) {
            throw new IllegalArgumentException("反馈实体不能为空");
        }

        try {
            feedbackMapper.insert(feedback);
            return feedback;
        } catch (Exception e) {
            log.error("保存反馈失败: {}", feedback, e);
            throw new RuntimeException("保存反馈失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<DivinationFeedbackDTO> getFeedbackByUserId(Integer userId, Integer pageNum, Integer pageSize) {
        // 参数校验
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        // 设置默认分页参数
        int actualPageNum = pageNum != null ? pageNum : 1;
        int actualPageSize = pageSize != null ? Math.min(pageSize, MAX_PAGE_SIZE) : DEFAULT_PAGE_SIZE;

        try {
            return feedbackMapper.findFeedbackByUserId(userId);
        } catch (Exception e) {
            log.error("获取用户反馈历史失败: userId={}, pageNum={}, pageSize={}",
                    userId, actualPageNum, actualPageSize, e);
            throw new RuntimeException("获取用户反馈历史失败: " + e.getMessage());
        }
    }
    
    @Override
    public Map<String, Double> getHexagramAccuracyRates() {
        try {
            List<DivinationFeedbackDO> allFeedback = feedbackMapper.selectList(null);
            
            // 按卦象分组并计算准确率
            return allFeedback.stream()
                    .filter(f -> f.getOriginalHexagram() != null && f.getIsAccurate() != null)
                    .collect(Collectors.groupingBy(
                            DivinationFeedbackDO::getOriginalHexagram,
                            Collectors.averagingDouble(f -> f.getIsAccurate() ? 1.0 : 0.0)))
                    .entrySet().stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            entry -> Math.round(entry.getValue() * 100.0) / 100.0)); // 保留两位小数
        } catch (Exception e) {
            log.error("获取卦象准确率统计失败", e);
            throw new RuntimeException("获取卦象准确率统计失败: " + e.getMessage());
        }
    }
    
    @Override
    public Map<String, Double> getCityAccuracyRates() {
        try {
            List<DivinationFeedbackDO> allFeedback = feedbackMapper.selectList(null);
            
            // 按城市分组并计算准确率
            return allFeedback.stream()
                    .filter(f -> f.getUserCity() != null && f.getIsAccurate() != null)
                    .collect(Collectors.groupingBy(
                            DivinationFeedbackDO::getUserCity,
                            Collectors.averagingDouble(f -> f.getIsAccurate() ? 1.0 : 0.0)))
                    .entrySet().stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            entry -> Math.round(entry.getValue() * 100.0) / 100.0)); // 保留两位小数
        } catch (Exception e) {
            log.error("获取城市准确率统计失败", e);
            throw new RuntimeException("获取城市准确率统计失败: " + e.getMessage());
        }
    }
    
    @Override
    public Map<String, Double> getMoodAccuracyRates() {
        try {
            List<DivinationFeedbackDO> allFeedback = feedbackMapper.selectList(null);
            
            // 按心情分组并计算准确率
            return allFeedback.stream()
                    .filter(f -> f.getUserMood() != null && f.getIsAccurate() != null)
                    .collect(Collectors.groupingBy(
                            DivinationFeedbackDO::getUserMood,
                            Collectors.averagingDouble(f -> f.getIsAccurate() ? 1.0 : 0.0)))
                    .entrySet().stream()
                    .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            entry -> Math.round(entry.getValue() * 100.0) / 100.0)); // 保留两位小数
        } catch (Exception e) {
            log.error("获取心情准确率统计失败", e);
            throw new RuntimeException("获取心情准确率统计失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean analyzeAndUpdateWeights() {
        try {
            // 这个方法的实现可能需要与权重系统集成
            // 当前仅记录日志
            log.info("分析反馈数据并更新权重");
            return true;
        } catch (Exception e) {
            log.error("分析反馈数据并更新权重失败", e);
            return false;
        }
    }
    
    @Override
    public double getUserAccuracyRate(Long userId) {
        // 参数校验
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        try {
            QueryWrapper<DivinationFeedbackDO> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", userId);
            wrapper.isNotNull("is_accurate");
            
            List<DivinationFeedbackDO> userFeedback = feedbackMapper.selectList(wrapper);
            
            if (userFeedback.isEmpty()) {
                return 0.0;
            }
            
            long accurateCount = userFeedback.stream()
                    .filter(f -> f.getIsAccurate() != null && f.getIsAccurate())
                    .count();
            
            return (double) accurateCount / userFeedback.size();
        } catch (Exception e) {
            log.error("获取用户准确率失败: userId={}", userId, e);
            return 0.0;
        }
    }

    @Override
    public long countByUserId(Integer userId) {
        // 参数校验
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        try {
            return feedbackMapper.countByUserId(userId);
        } catch (Exception e) {
            log.error("统计用户反馈数量失败: userId={}", userId, e);
            return 0;
        }
    }
    
    @Override
    public boolean deleteFeedback(Long feedbackId, Integer userId) {
        // 参数校验
        if (feedbackId == null) {
            throw new IllegalArgumentException("反馈ID不能为空");
        }

        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        try {
            QueryWrapper<DivinationFeedbackDO> wrapper = new QueryWrapper<>();
            wrapper.eq("id", feedbackId);
            wrapper.eq("user_id", userId);
            
            return feedbackMapper.delete(wrapper) > 0;
        } catch (Exception e) {
            log.error("删除反馈失败: feedbackId={}, userId={}", feedbackId, userId, e);
            return false;
        }
    }
}